//! 联系方式相关的数据结构

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// ContactMech实体 - 联系方式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContactMech {
    pub contact_mech_id: String,
    pub contact_mech_type_id: String,
    pub info_string: Option<String>,
}

/// PostalAddress实体 - 邮政地址
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostalAddress {
    pub contact_mech_id: String,
    pub to_name: Option<String>,
    pub attn_name: Option<String>,
    pub address1: Option<String>,
    pub address2: Option<String>,
    pub house_number: Option<String>,
    pub house_number_ext: Option<String>,
    pub directions: Option<String>,
    pub city: Option<String>,
    pub city_geo_id: Option<String>,
    pub postal_code: Option<String>,
    pub postal_code_ext: Option<String>,
    pub country_geo_id: Option<String>,
    pub state_province_geo_id: Option<String>,
    pub county_geo_id: Option<String>,
    pub municipality_geo_id: Option<String>,
    pub postal_code_geo_id: Option<String>,
    pub geo_point_id: Option<String>,
}

/// TelecomNumber实体 - 电话号码
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TelecomNumber {
    pub contact_mech_id: String,
    pub country_code: Option<String>,
    pub area_code: Option<String>,
    pub contact_number: String,
    pub ask_for_name: Option<String>,
}

/// PartyContactMech实体 - 参与方联系方式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PartyContactMech {
    pub party_id: String,
    pub contact_mech_id: String,
    pub from_date: DateTime<Utc>,
    pub thru_date: Option<DateTime<Utc>>,
    pub role_type_id: Option<String>,
    pub allow_solicitation: Option<bool>,
    pub extension: Option<String>,
    pub verified: Option<bool>,
    pub comments: Option<String>,
    pub years_with_contact_mech: Option<f64>,
    pub months_with_contact_mech: Option<f64>,
}

/// PartyContactMechPurpose实体 - 参与方联系方式用途
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PartyContactMechPurpose {
    pub party_id: String,
    pub contact_mech_id: String,
    pub contact_mech_purpose_type_id: String,
    pub from_date: DateTime<Utc>,
    pub thru_date: Option<DateTime<Utc>>,
}

/// ContactMechType实体 - 联系方式类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContactMechType {
    pub contact_mech_type_id: String,
    pub parent_type_id: Option<String>,
    pub has_table: Option<bool>,
    pub description: Option<String>,
}

/// ContactMechPurposeType实体 - 联系方式用途类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContactMechPurposeType {
    pub contact_mech_purpose_type_id: String,
    pub parent_type_id: Option<String>,
    pub has_table: Option<bool>,
    pub description: Option<String>,
}

impl ContactMech {
    /// 创建新的ContactMech实例
    pub fn new(contact_mech_id: String, contact_mech_type_id: String) -> Self {
        Self {
            contact_mech_id,
            contact_mech_type_id,
            info_string: None,
        }
    }

    /// 创建电子邮件联系方式
    pub fn create_email(contact_mech_id: String, email: String) -> Self {
        Self {
            contact_mech_id,
            contact_mech_type_id: "EMAIL_ADDRESS".to_string(),
            info_string: Some(email),
        }
    }

    /// 创建网站联系方式
    pub fn create_web_address(contact_mech_id: String, url: String) -> Self {
        Self {
            contact_mech_id,
            contact_mech_type_id: "WEB_ADDRESS".to_string(),
            info_string: Some(url),
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("contactMechId".to_string(), self.contact_mech_id.clone());
        data.insert("contactMechTypeId".to_string(), self.contact_mech_type_id.clone());
        
        if let Some(ref info_string) = self.info_string {
            data.insert("infoString".to_string(), info_string.clone());
        } else {
            // 确保infoString字段存在，即使是空值
            data.insert("infoString".to_string(), "".to_string());
        }
        
        data
    }

    /// 从HashMap创建ContactMech实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let contact_mech_id = data.get("contactMechId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechId".to_string())))?
            .clone();
        let contact_mech_type_id = data.get("contactMechTypeId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechTypeId".to_string())))?
            .clone();
        
        Ok(Self {
            contact_mech_id,
            contact_mech_type_id,
            info_string: data.get("infoString").cloned(),
        })
    }
}

impl PostalAddress {
    /// 创建新的PostalAddress实例
    pub fn new(contact_mech_id: String) -> Self {
        Self {
            contact_mech_id,
            to_name: None,
            attn_name: None,
            address1: None,
            address2: None,
            house_number: None,
            house_number_ext: None,
            directions: None,
            city: None,
            city_geo_id: None,
            postal_code: None,
            postal_code_ext: None,
            country_geo_id: None,
            state_province_geo_id: None,
            county_geo_id: None,
            municipality_geo_id: None,
            postal_code_geo_id: None,
            geo_point_id: None,
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("contactMechId".to_string(), self.contact_mech_id.clone());
        
        if let Some(ref to_name) = self.to_name {
            data.insert("toName".to_string(), to_name.clone());
        }
        if let Some(ref attn_name) = self.attn_name {
            data.insert("attnName".to_string(), attn_name.clone());
        }
        if let Some(ref address1) = self.address1 {
            data.insert("address1".to_string(), address1.clone());
        }
        if let Some(ref address2) = self.address2 {
            data.insert("address2".to_string(), address2.clone());
        }
        if let Some(ref city) = self.city {
            data.insert("city".to_string(), city.clone());
        }
        if let Some(ref postal_code) = self.postal_code {
            data.insert("postalCode".to_string(), postal_code.clone());
        }
        if let Some(ref country_geo_id) = self.country_geo_id {
            data.insert("countryGeoId".to_string(), country_geo_id.clone());
        }
        if let Some(ref state_province_geo_id) = self.state_province_geo_id {
            data.insert("stateProvinceGeoId".to_string(), state_province_geo_id.clone());
        }
        // 添加其他字段...
        
        data
    }

    /// 从HashMap创建PostalAddress实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let contact_mech_id = data.get("contactMechId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechId".to_string())))?
            .clone();
        
        Ok(Self {
            contact_mech_id,
            to_name: data.get("toName").cloned(),
            attn_name: data.get("attnName").cloned(),
            address1: data.get("address1").cloned(),
            address2: data.get("address2").cloned(),
            house_number: data.get("houseNumber").cloned(),
            house_number_ext: data.get("houseNumberExt").cloned(),
            directions: data.get("directions").cloned(),
            city: data.get("city").cloned(),
            city_geo_id: data.get("cityGeoId").cloned(),
            postal_code: data.get("postalCode").cloned(),
            postal_code_ext: data.get("postalCodeExt").cloned(),
            country_geo_id: data.get("countryGeoId").cloned(),
            state_province_geo_id: data.get("stateProvinceGeoId").cloned(),
            county_geo_id: data.get("countyGeoId").cloned(),
            municipality_geo_id: data.get("municipalityGeoId").cloned(),
            postal_code_geo_id: data.get("postalCodeGeoId").cloned(),
            geo_point_id: data.get("geoPointId").cloned(),
        })
    }
}

impl TelecomNumber {
    /// 创建新的TelecomNumber实例
    pub fn new(contact_mech_id: String, contact_number: String) -> Self {
        Self {
            contact_mech_id,
            country_code: None,
            area_code: None,
            contact_number,
            ask_for_name: None,
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("contactMechId".to_string(), self.contact_mech_id.clone());
        data.insert("contactNumber".to_string(), self.contact_number.clone());
        
        if let Some(ref country_code) = self.country_code {
            data.insert("countryCode".to_string(), country_code.clone());
        }
        if let Some(ref area_code) = self.area_code {
            data.insert("areaCode".to_string(), area_code.clone());
        }
        if let Some(ref ask_for_name) = self.ask_for_name {
            data.insert("askForName".to_string(), ask_for_name.clone());
        }
        
        data
    }

    /// 从HashMap创建TelecomNumber实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let contact_mech_id = data.get("contactMechId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechId".to_string())))?
            .clone();
        let contact_number = data.get("contactNumber")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactNumber".to_string())))?
            .clone();
        
        Ok(Self {
            contact_mech_id,
            country_code: data.get("countryCode").cloned(),
            area_code: data.get("areaCode").cloned(),
            contact_number,
            ask_for_name: data.get("askForName").cloned(),
        })
    }
}

impl PartyContactMech {
    /// 创建新的PartyContactMech实例
    pub fn new(party_id: String, contact_mech_id: String) -> Self {
        Self {
            party_id,
            contact_mech_id,
            from_date: Utc::now(),
            thru_date: None,
            role_type_id: None,
            allow_solicitation: Some(true),
            extension: None,
            verified: Some(false),
            comments: None,
            years_with_contact_mech: None,
            months_with_contact_mech: None,
        }
    }

    /// 检查联系方式是否有效（未过期）
    pub fn is_active(&self) -> bool {
        match self.thru_date {
            Some(thru_date) => Utc::now() <= thru_date,
            None => true,
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("partyId".to_string(), self.party_id.clone());
        data.insert("contactMechId".to_string(), self.contact_mech_id.clone());
        data.insert("fromDate".to_string(), self.from_date.to_rfc3339());
        
        if let Some(thru_date) = self.thru_date {
            data.insert("thruDate".to_string(), thru_date.to_rfc3339());
        }
        if let Some(ref role_type_id) = self.role_type_id {
            data.insert("roleTypeId".to_string(), role_type_id.clone());
        }
        if let Some(allow_solicitation) = self.allow_solicitation {
            data.insert("allowSolicitation".to_string(), if allow_solicitation { "Y" } else { "N" }.to_string());
        }
        if let Some(ref extension) = self.extension {
            data.insert("extension".to_string(), extension.clone());
        }
        if let Some(verified) = self.verified {
            data.insert("verified".to_string(), if verified { "Y" } else { "N" }.to_string());
        }
        if let Some(ref comments) = self.comments {
            data.insert("comments".to_string(), comments.clone());
        }
        
        data
    }

    /// 从HashMap创建PartyContactMech实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let party_id = data.get("partyId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing partyId".to_string())))?
            .clone();
        let contact_mech_id = data.get("contactMechId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechId".to_string())))?
            .clone();
        let from_date = data.get("fromDate")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing fromDate".to_string())))
            .and_then(|s| DateTime::parse_from_rfc3339(s)
                .map_err(|_| Box::new(PartyModError::InvalidData("Invalid fromDate format".to_string()))))
            .map(|dt| dt.with_timezone(&Utc))?;
        
        let thru_date = data.get("thruDate")
            .and_then(|s| DateTime::parse_from_rfc3339(s).ok())
            .map(|dt| dt.with_timezone(&Utc));
        
        let allow_solicitation = data.get("allowSolicitation")
            .map(|s| s == "Y");
        
        let verified = data.get("verified")
            .map(|s| s == "Y");
        
        Ok(Self {
            party_id,
            contact_mech_id,
            from_date,
            thru_date,
            role_type_id: data.get("roleTypeId").cloned(),
            allow_solicitation,
            extension: data.get("extension").cloned(),
            verified,
            comments: data.get("comments").cloned(),
            years_with_contact_mech: data.get("yearsWithContactMech")
                .and_then(|s| s.parse().ok()),
            months_with_contact_mech: data.get("monthsWithContactMech")
                .and_then(|s| s.parse().ok()),
        })
    }
}

impl ContactMechType {
    /// 创建新的ContactMechType实例
    pub fn new(contact_mech_type_id: String, description: Option<String>) -> Self {
        Self {
            contact_mech_type_id,
            parent_type_id: None,
            has_table: None,
            description,
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("contactMechTypeId".to_string(), self.contact_mech_type_id.clone());
        
        if let Some(ref parent_type_id) = self.parent_type_id {
            data.insert("parentTypeId".to_string(), parent_type_id.clone());
        }
        if let Some(has_table) = self.has_table {
            data.insert("hasTable".to_string(), if has_table { "Y" } else { "N" }.to_string());
        }
        if let Some(ref description) = self.description {
            data.insert("description".to_string(), description.clone());
        }
        
        data
    }

    /// 从HashMap创建ContactMechType实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let contact_mech_type_id = data.get("contactMechTypeId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechTypeId".to_string())))?
            .clone();
        
        let has_table = data.get("hasTable")
            .map(|s| s == "Y");
        
        Ok(Self {
            contact_mech_type_id,
            parent_type_id: data.get("parentTypeId").cloned(),
            has_table,
            description: data.get("description").cloned(),
        })
    }
}

impl ContactMechPurposeType {
    /// 创建新的ContactMechPurposeType实例
    pub fn new(contact_mech_purpose_type_id: String, description: Option<String>) -> Self {
        Self {
            contact_mech_purpose_type_id,
            parent_type_id: None,
            has_table: None,
            description,
        }
    }

    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("contactMechPurposeTypeId".to_string(), self.contact_mech_purpose_type_id.clone());
        
        if let Some(ref parent_type_id) = self.parent_type_id {
            data.insert("parentTypeId".to_string(), parent_type_id.clone());
        }
        if let Some(has_table) = self.has_table {
            data.insert("hasTable".to_string(), if has_table { "Y" } else { "N" }.to_string());
        }
        if let Some(ref description) = self.description {
            data.insert("description".to_string(), description.clone());
        }
        
        data
    }

    /// 从HashMap创建ContactMechPurposeType实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let contact_mech_purpose_type_id = data.get("contactMechPurposeTypeId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechPurposeTypeId".to_string())))?
            .clone();
        
        let has_table = data.get("hasTable")
            .map(|s| s == "Y");
        
        Ok(Self {
            contact_mech_purpose_type_id,
            parent_type_id: data.get("parentTypeId").cloned(),
            has_table,
            description: data.get("description").cloned(),
        })
    }
}

impl PartyContactMechPurpose {
    /// 转换为HashMap用于数据库操作
    pub fn to_data_row(&self) -> HashMap<String, String> {
        let mut data = HashMap::new();
        data.insert("partyId".to_string(), self.party_id.clone());
        data.insert("contactMechId".to_string(), self.contact_mech_id.clone());
        data.insert("contactMechPurposeTypeId".to_string(), self.contact_mech_purpose_type_id.clone());
        data.insert("fromDate".to_string(), self.from_date.to_rfc3339());
        
        if let Some(thru_date) = self.thru_date {
            data.insert("thruDate".to_string(), thru_date.to_rfc3339());
        }
        
        data
    }

    /// 从HashMap创建PartyContactMechPurpose实例
    pub fn from_data_row(data: &HashMap<String, String>) -> crate::Result<Self> {
        use crate::PartyModError;
        
        let party_id = data.get("partyId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing partyId".to_string())))?
            .clone();
        let contact_mech_id = data.get("contactMechId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechId".to_string())))?
            .clone();
        let contact_mech_purpose_type_id = data.get("contactMechPurposeTypeId")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing contactMechPurposeTypeId".to_string())))?
            .clone();
        let from_date = data.get("fromDate")
            .ok_or_else(|| Box::new(PartyModError::InvalidData("Missing fromDate".to_string())))
            .and_then(|s| DateTime::parse_from_rfc3339(s)
                .map_err(|_| Box::new(PartyModError::InvalidData("Invalid fromDate format".to_string()))))
            .map(|dt| dt.with_timezone(&Utc))?;
        
        let thru_date = data.get("thruDate")
            .and_then(|s| DateTime::parse_from_rfc3339(s).ok())
            .map(|dt| dt.with_timezone(&Utc));
        
        Ok(Self {
            party_id,
            contact_mech_id,
            contact_mech_purpose_type_id,
            from_date,
            thru_date,
        })
    }
}